package com.elasticsearch.util;

import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.elasticsearch.entity.Product;


/**   
 * @ClassName:     ElasticsearchFactory   
 * @Description:   获取连接工具类
 * @author:        wl
 * @date:          2017年10月30日 下午3:37:50     
 */  
public class ElasticsearchFactory {

	private volatile static TransportClient client = null; 	
	
    @SuppressWarnings("resource")
	public static TransportClient getClient() {  
        if(client==null){  
            synchronized (ElasticsearchFactory.class) {
            	try {
					if(client==null){  
				    	ResourceBundle bundle = ResourceBundle.getBundle("elasticsearch");
				    	String host = bundle.getString("elasticsearch.host");
				    	int port = Integer.parseInt(bundle.getString("elasticsearch.port"));
				    	String clusterName = bundle.getString("elasticsearch.cluster.name");
					    Settings settings = Settings.builder().put("cluster.name", clusterName)  
					            .put("client.transport.sniff", false)//自动嗅探整个集群的状态，把集群中其它机器的ip地址加到客户端中
					            .build();
					    System.out.println("host:"+host);
					    System.out.println("port:"+port);
					    System.out.println("clusterName:"+clusterName);
					    client = new PreBuiltTransportClient(settings)
					    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port)); 
//					    for (String  hosts : host.split(",")) {
//					    	InetSocketTransportAddress address = new InetSocketTransportAddress(InetAddress.getByName(hosts),port);
//					    	client.addTransportAddress(address);
//						}                    
					}
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
			}
        }  
        return client; 
    }	
    
    public static int index(String index,String type,String id,String source){
    	IndexResponse response = ElasticsearchFactory.getClient().prepareIndex(index, type,id)
    	        .setSource(source,XContentType.JSON)
    	        .get(); 
    	return response.status().getStatus();
    }
    
    public static String get(String index,String type,String id){
    	GetResponse response = ElasticsearchFactory.getClient().prepareGet(index, type, id)
    			.execute()
    			.actionGet();
		return response.getSourceAsString();
    }
    
    public static int delete(String index,String type,String id){
    	DeleteResponse response =  ElasticsearchFactory.getClient().prepareDelete(index, type, id)
    	 .execute().actionGet();
    	return response.status().getStatus();
    }
    
    public static int update(String index,String type,String id,String source){
    	UpdateResponse response = ElasticsearchFactory.getClient().prepareUpdate(index, type, id)
    				.setDoc(source, XContentType.JSON).execute().actionGet();
		return response.status().getStatus();
    }
    
    public static <T> List<T> search(String index,String type,QueryBuilder queryBuilder,int from,int page,TypeReference<Product> typeReference){
    	List<T> result = new ArrayList<T>();
    	SearchResponse response = ElasticsearchFactory.getClient().prepareSearch(index)
    			.setTypes(type)
    			.setQuery(queryBuilder)
    			.setFrom(from)
    			.setSize(page)
//    			.setFetchSource(new String[]{"user","postDate"}, null)
//    			.addSort("postDate", SortOrder.ASC)
//    			.addScriptField(name, script)
    			.get();
    	for (SearchHit hit : response.getHits().getHits()) {
    		System.out.println(hit.getSourceAsString());
    		T t = JSON.parseObject(hit.getSourceAsString(), typeReference.getType());
    		result.add(t);
		}
    	return result;
    }
    
    public static void main(String[] args) {
    	String json = "{    \"content\": \"修改内容\",    \"id\": 9999,    \"sid\": \"修改sid\",    \"title\": \"修改title\"}";
//    	System.out.println(index("create", "test", "10004", json));
//    	System.out.println(get("create", "test", "10004"));
//    	System.out.println(delete("create", "test", "10004"));
//    	System.out.println(update("create", "test", "10003",json));
//    	QueryBuilder qb = QueryBuilders.matchPhrasePrefixQuery("user", "kimchy");
//    	QueryBuilder bb = QueryBuilders.matchPhrasePrefixQuery("book_name", "篮坛教皇");
    	QueryBuilder q = QueryBuilders.queryStringQuery(" content:修改内容  ");
    	List<Product> s = search("test", "test",q, 0, 10,new TypeReference<Product>(){});
    	for (Product test : s) {
			System.out.println(test.getTitle());
		}
    	
//    	Product p =JSONObject.parseObject(json, Product.class);
//    	System.out.println(p.getTitle());
    	
//    	Type type = new TypeReference<Product>(){}.getType();
//    	List<Product> pp = testJson(type);
//    	System.out.println(pp.size());
//    	for (Product product : pp) {
//			System.out.println(product.getTitle());
//		}
    }
    
    
    public static <T> List<T> testJson(Type type){
    	String json = "{    \"content\": \"修改内容\",    \"id\": 9999,    \"sid\": \"修改sid\",    \"title\": \"修改title\"}";  	
    	System.out.println(type.getClass());
    	T tt =JSON.parseObject(json,type);
    	List<T> list = new ArrayList<T>();
    	list.add(tt);
    	System.out.println(tt.getClass());
    	return list;
    }
 
}
